package com.sjme.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sjme.Feign.CandidateClient;
import com.sjme.Feign.UserClient;
import com.sjme.domain.interview.CandidateInterviewer;
import com.sjme.domain.candidate.Candidate;
import com.sjme.domain.interview.InterviewEvaluation;
import com.sjme.domain.interview.InterviewInfo;
import com.sjme.domain.user.User;
import com.sjme.domain.interview.ArrangeInterview;
import com.sjme.domain.candidate.dto.CandidateDto;
import com.sjme.domain.interview.dto.InterviewInfoDto;
import com.sjme.domain.interview.vo.InterviewInfoVo;
import com.sjme.mapper.InterviewInfoMapper;
import com.sjme.service.ICandidateInterviewerService;
import com.sjme.service.InterviewEvaluationService;
import com.sjme.service.InterviewInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.utils.NumericUUIDUtil;
import com.utils.Result;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import static com.sjme.util.CommonUtil.convertIPage;


/**
 * <p>
 * 面试管理表 服务实现类
 * </p>
 *
 * @author LY
 * @since 2025-10-12
 */
@Slf4j
@Service
public class InterviewInfoServiceImpl extends ServiceImpl<InterviewInfoMapper, InterviewInfo> implements InterviewInfoService {
    @Autowired
    private ICandidateInterviewerService candidateInterviewerService;
    @Autowired
    private InterviewEvaluationService interviewEvaluationService;
    @Autowired
    private UserClient userClient;
    @Autowired
    private CandidateClient candidateClient;
    @Autowired
    private StringRedisTemplate redisTemplate;

    @GlobalTransactional
    @Override
    public Result arrangeInterview(ArrangeInterview arrangeInterview) {
        try {
            // 1.保存面试关联信息：候选人 和 面试官
            List<String> interviewerIdList = arrangeInterview.getInterviewerIdList();
            List<String> candidateIdList = arrangeInterview.getCandidateIdList();
            if (interviewerIdList == null || interviewerIdList.isEmpty() || candidateIdList == null || candidateIdList.isEmpty()) {
                throw new RuntimeException("安排面试参数中的候选人和面试官信息为空，请检查！");
            }
            List<InterviewInfo> interviewInfoList = new ArrayList<>();
            List<CandidateInterviewer> candidateInterviewers = new ArrayList<>();
            List<InterviewEvaluation> interviewEvaluations = new ArrayList<>();
            for (String candidateId : candidateIdList) {
                // 2.获取面试基本信息
                InterviewInfo interviewInfo = new InterviewInfo();
                BeanUtils.copyProperties(arrangeInterview,interviewInfo);
                interviewInfo.setCandidateId(candidateId);
                // 3.保存面试基本信息
                String interviewInfoId = NumericUUIDUtil.generateShortNumericUUID(16);
                interviewInfo.setId(interviewInfoId);
                interviewInfoList.add(interviewInfo);
                for (String interviewerId : interviewerIdList) {
                    // 面试评价信息
                    String interviewEvaluationId = NumericUUIDUtil.generateShortNumericUUID(16);
                    interviewEvaluations.add(new InterviewEvaluation(interviewEvaluationId));
                    // 面试关联信息：面试信息 - 面试官 - 面试评价
                    candidateInterviewers.add(new CandidateInterviewer(interviewInfoId, interviewerId,interviewEvaluationId,candidateId));
                }
            }
            this.saveBatch(interviewInfoList);
            interviewEvaluationService.saveBatch(interviewEvaluations);
            candidateInterviewerService.saveBatch(candidateInterviewers);
        } catch (BeansException e) {
            throw new RuntimeException(e);
        }
        return Result.success(null);
    }

    @Override
    public IPage<InterviewInfoVo> getInterviewInfo(InterviewInfoDto interviewInfo) {
        // 获取传参
        Integer current = interviewInfo.getCurrent() == null ? 1 : interviewInfo.getCurrent();
        Integer size = interviewInfo.getSize() == null ? 6 : interviewInfo.getSize();
        IPage<InterviewInfoVo> result = new Page<>(current,size);
        String title = interviewInfo.getTitle(); // 面试标题
        String interviewerName = interviewInfo.getInterviewerName(); // 面试官名称
        String candidateNameStr = interviewInfo.getCandidateName(); // 候选人名称
        // 1.根据面试官名称构建查询信息
        User userParam = new User();
        userParam.setName(interviewerName);
        List<User> users = userClient.queryUserByCondition(userParam);
        log.info("用户信息为======>{}",users);
        if (users.isEmpty()){
            return result;
        }
        // 1-1 面试官id列表
        List<String> interviewerIdList = users.stream().map(User::getId).collect(Collectors.toList());


        // 2.根据面试官信息获取(面试-面试官)的关联信息
        List<CandidateInterviewer> candidateInterviewers = candidateInterviewerService.list(Wrappers.<CandidateInterviewer>lambdaQuery().
                in(CandidateInterviewer::getInterviewerId, interviewerIdList));

        // 3.根据传递的候选人名称限制候选人
        CandidateDto candidateParam = new CandidateDto();
        candidateParam.setName(candidateNameStr);
        List<Candidate> candidateInfos = candidateClient.queryCandidateByCondition(candidateParam);
        List<String> candidateIds = candidateInfos.stream().map(Candidate::getId).collect(Collectors.toList());

        // 4.获取面试信息
        List<String> interviewInfoIdList = candidateInterviewers.stream().map(CandidateInterviewer::getInterviewInfoId).collect(Collectors.toList());
        IPage<InterviewInfo> page = new Page<>(current, size);
        this.page(page,
                Wrappers.<InterviewInfo>lambdaQuery()
                        .in(!interviewInfoIdList.isEmpty(),InterviewInfo::getId, interviewInfoIdList)
                        .in(!candidateIds.isEmpty(),InterviewInfo::getCandidateId, candidateIds)
                        .like(StringUtils.isNotBlank(title),InterviewInfo::getTitle, title)
        );
        List<InterviewInfo> interviewInfos = page.getRecords();

        // 5.从面试信息中获取候选人id集合，并查出对应候选人信息
        List<String> candidateIdList = interviewInfos.stream().map(InterviewInfo::getCandidateId).collect(Collectors.toList());
        if (candidateIdList.isEmpty()){
            return result;
        }
        List<Candidate> candidates = candidateClient.queryCandidateByIdsNew(candidateIdList);
        Map<String,String> candidateIdAndNameMap = new HashMap<>();
        candidates.forEach(item -> {
            candidateIdAndNameMap.put(item.getId(),item.getName());
        });

        // 5.根据面试信息id获取该面试所参与的面试官
        Map<String, List<User>> interviewerIdAndInfoMap = this.getInterviewerNamesMapByInterviewInfoIdList(interviewInfoIdList);

        // 5.获取完整的面试信息
        result = convertIPage(page, InterviewInfoVo.class, info -> {
            InterviewInfoVo interviewInfoVo = new InterviewInfoVo();
            BeanUtils.copyProperties(info, interviewInfoVo);
            // 设置额外字段
            String interviewInfoId = interviewInfoVo.getId();
            String candidateId = interviewInfoVo.getCandidateId();
            // 5-1将候选人信息设置到面试信息中
            String candidateName = candidateIdAndNameMap.get(candidateId);
            interviewInfoVo.setCandidateName(candidateName);
            // 5-2将面试官信息设置到面试信息中
            List<User> interviewerList = interviewerIdAndInfoMap.get(interviewInfoId);
            List<String> interviewerNameList = interviewerList.stream().map(User::getName).collect(Collectors.toList());
            List<String> interviewerIds = interviewerList.stream().map(User::getId).collect(Collectors.toList());
            String interviewerNames = String.join(",", interviewerNameList);
            interviewInfoVo.setInterviewersName(interviewerNames);
            interviewInfoVo.setInterviewerIdList(interviewerIds);
            return interviewInfoVo;
        });
        return result;
    }

    /**
     * 根据面试信息id获取该面试中参与的面试官名称信息
     * @param interviewInfoIdList 面试信息id列表
     */
    @Override
    public Map<String, List<User>> getInterviewerNamesMapByInterviewInfoIdList(List<String> interviewInfoIdList) {
        Map<String, List<User>> interviewerMap = new HashMap<>();

        List<CandidateInterviewer> candidateInterviewers = candidateInterviewerService.list(Wrappers.<CandidateInterviewer>lambdaQuery()
                                                                        .in(CandidateInterviewer::getInterviewInfoId, interviewInfoIdList));
        if (candidateInterviewers == null || candidateInterviewers.isEmpty()) {
            return interviewerMap;
        }
        List<String> interviewerIdList = candidateInterviewers.stream().map(CandidateInterviewer::getInterviewerId).collect(Collectors.toList());
        List<User> interviewerList = userClient.queryUserByIds(interviewerIdList);
        // 面试官id : 面试官名称
        Map<String,User> interviewerIdAndNameMap = new HashMap<>();
        interviewerList.forEach(item -> {
            interviewerIdAndNameMap.put(item.getId(),item);
        });
        for (String interviewInfoId : interviewInfoIdList) {
            List<User> interviewers = new ArrayList<>();
            for (CandidateInterviewer candidateInterviewer : candidateInterviewers) {
                if (candidateInterviewer.getInterviewInfoId().equals(interviewInfoId)) {
                    String interviewerId = candidateInterviewer.getInterviewerId();
                    User interviewer = interviewerIdAndNameMap.get(interviewerId);
                    interviewers.add(interviewer);
                }
            }
            if (!interviewers.isEmpty()){
                interviewerMap.put(interviewInfoId, interviewers);
            }
        }
        // todo 返回的数据改为<面试信息id : 面试官信息集合>
        return interviewerMap;
    }
}
